﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Input;

namespace XNAGuiLib.GuiLibAction
{
    public class MouseAction : Action
    {
        //
        #region Field - Input
        protected Inputs _input;
        /// <summary>
        /// gets or sets the input for this MouseAction
        /// </summary>
        public Inputs Input
        {
            get
            {
                return _input;
            }
            set
            {
                _input = value;
            }
        }
        #endregion
        //
        #region Field - MouseButton
        private MouseButtons _mouseButton;
        /// <summary>
        /// gets or sets the MouseButton for this Action
        /// </summary>
        public MouseButtons MouseButton
        {
            get
            {
                return _mouseButton;
            }
            set
            {
                _mouseButton = value;
            }
        }
        #endregion
        //
        //
        #region Enumeration - Inputs
        public enum Inputs
        {
            /// <summary>
            /// button of the mouse down
            /// </summary>
            MouseButtonDown,
            /// <summary>
            /// button of the mouse pressed (down & released)
            /// </summary>
            MouseButtonPressed,
            /// <summary>
            /// button of the mouse released
            /// </summary>
            MouseButtonReleased
        }
        #endregion
        //
        #region Enumeration - MouseButtons
        public enum MouseButtons
        {
            /// <summary>
            /// left mouse button
            /// </summary>
            Left,
            /// <summary>
            /// middle mouse button
            /// </summary>
            Middle,
            /// <summary>
            /// right mouse button
            /// </summary>
            Right
        }
        #endregion
        //
        //
        #region Constructor - MouseAction()
        public MouseAction()
        { }
        #endregion
        //
        //
        // check for the CommandType and if the Action's left mouse button is pressed, down or released
        // executes a command depending on the CommandType
        #region Private Method - CheckMouseLeftButton()
        private void CheckMouseLeftButton()
        {
            // Check Left Mouse Button Down
            if (_input == Inputs.MouseButtonDown && _ms.LeftButton == ButtonState.Pressed)
            {
                if (_type == CommandType.Hide && CheckCoordinates(_ms))
                {
                    ExecuteActionHide();
                }
                else if (_type == CommandType.Show && CheckCoordinates(_ms))
                {
                    ExecuteActionShow();
                }
                else if (_type == CommandType.Move && _initialMouseDownInsideInterfaceObject && (_ms.X != _oms.X || _ms.Y != _oms.Y))
                {
                    ExecuteActionMove(_ms, _oms);
                }
                else if (_type == CommandType.Custom && CheckCoordinates(_ms))
                {
                    Execute();
                }
            }
            // Check Left Mouse Button Released
            else if (_input == Inputs.MouseButtonReleased && _ms.LeftButton == ButtonState.Released)
            {
                if (_type == CommandType.Hide && CheckCoordinates(_ms))
                {
                    ExecuteActionHide();
                }
                else if (_type == CommandType.Show && CheckCoordinates(_ms))
                {
                    ExecuteActionShow();
                }
                else if (_type == CommandType.Move && _initialMouseDownInsideInterfaceObject && (_ms.X != _oms.X || _ms.Y != _oms.Y))
                {
                    ExecuteActionMove(_ms, _oms);
                }
                else if (_type == CommandType.Custom && CheckCoordinates(_ms))
                {
                    Execute();
                }
            }
            // Check Left Mouse Button Pressed (down & released)
            else if (_input == Inputs.MouseButtonPressed && _ms.LeftButton == ButtonState.Released && _oms.LeftButton == ButtonState.Pressed)
            {
                if (_type == CommandType.Hide && CheckCoordinates(_ms))
                {
                    ExecuteActionHide();
                }
                else if (_type == CommandType.Show && CheckCoordinates(_ms))
                {
                    ExecuteActionShow();
                }
                else if (_type == CommandType.Move && _initialMouseDownInsideInterfaceObject && (_ms.X != _oms.X || _ms.Y != _oms.Y))
                {
                    ExecuteActionMove(_ms, _oms);
                }
                else if (_type == CommandType.Custom && CheckCoordinates(_ms))
                {
                    Execute();
                }
            }
        }
        #endregion
        // check for the CommandType and if the Action's middle mouse button is pressed, down or released
        // executes a command depending on the CommandType
        #region Private Method - CheckMouseMidButton()
        private void CheckMouseMidButton()
        {
            // Check Middle Mouse Button Down
            if (_input == Inputs.MouseButtonDown && _ms.MiddleButton == ButtonState.Pressed)
            {
                if (_type == CommandType.Hide && CheckCoordinates(_ms))
                {
                    ExecuteActionHide();
                }
                else if (_type == CommandType.Show && CheckCoordinates(_ms))
                {
                    ExecuteActionShow();
                }
                else if (_type == CommandType.Move && _initialMouseDownInsideInterfaceObject && (_ms.X != _oms.X || _ms.Y != _oms.Y))
                {
                    ExecuteActionMove(_ms, _oms);
                }
                else if (_type == CommandType.Custom && CheckCoordinates(_ms))
                {
                    Execute();
                }
            }
            // Check Middle Mouse Button Released
            else if (_input == Inputs.MouseButtonReleased && _ms.MiddleButton == ButtonState.Released)
            {
                if (_type == CommandType.Hide && CheckCoordinates(_ms))
                {
                    ExecuteActionHide();
                }
                else if (_type == CommandType.Show && CheckCoordinates(_ms))
                {
                    ExecuteActionShow();
                }
                else if (_type == CommandType.Move && _initialMouseDownInsideInterfaceObject && (_ms.X != _oms.X || _ms.Y != _oms.Y))
                {
                    ExecuteActionMove(_ms, _oms);
                }
                else if (_type == CommandType.Custom && CheckCoordinates(_ms))
                {
                    Execute();
                }
            }
            // Check Middle Mouse Button Pressed (down & released)
            else if (_input == Inputs.MouseButtonPressed && _ms.MiddleButton == ButtonState.Released && _oms.MiddleButton == ButtonState.Pressed)
            {
                if (_type == CommandType.Hide && CheckCoordinates(_ms))
                {
                    ExecuteActionHide();
                }
                else if (_type == CommandType.Show && CheckCoordinates(_ms))
                {
                    ExecuteActionShow();
                }
                else if (_type == CommandType.Move && _initialMouseDownInsideInterfaceObject && (_ms.X != _oms.X || _ms.Y != _oms.Y))
                {
                    ExecuteActionMove(_ms, _oms);
                }
                else if (_type == CommandType.Custom && CheckCoordinates(_ms))
                {
                    Execute();
                }
            }
        }
        #endregion
        // check for the CommandType and if the Action's right mouse button is pressed, down or released
        // executes a command depending on the CommandType
        #region Private Method - CheckMouseRightButton()
        private void CheckMouseRightButton()
        {
            // Check Middle Mouse Button Down
            if (_input == Inputs.MouseButtonDown && _ms.RightButton == ButtonState.Pressed)
            {
                if (_type == CommandType.Hide && CheckCoordinates(_ms))
                {
                    ExecuteActionHide();
                }
                else if (_type == CommandType.Show && CheckCoordinates(_ms))
                {
                    ExecuteActionShow();
                }
                else if (_type == CommandType.Move && _initialMouseDownInsideInterfaceObject && (_ms.X != _oms.X || _ms.Y != _oms.Y))
                {
                    ExecuteActionMove(_ms, _oms);
                }
                else if (_type == CommandType.Custom && CheckCoordinates(_ms))
                {
                    Execute();
                }
            }
            // Check Middle Mouse Button Released
            else if (_input == Inputs.MouseButtonReleased && _ms.RightButton == ButtonState.Released)
            {
                if (_type == CommandType.Hide && CheckCoordinates(_ms))
                {
                    ExecuteActionHide();
                }
                else if (_type == CommandType.Show && CheckCoordinates(_ms))
                {
                    ExecuteActionShow();
                }
                else if (_type == CommandType.Move && _initialMouseDownInsideInterfaceObject && (_ms.X != _oms.X || _ms.Y != _oms.Y))
                {
                    ExecuteActionMove(_ms, _oms);
                }
                else if (_type == CommandType.Custom && CheckCoordinates(_ms))
                {
                    Execute();
                }
            }
            // Check Middle Mouse Button Pressed (down & released)
            else if (_input == Inputs.MouseButtonPressed && _ms.RightButton == ButtonState.Released && _oms.RightButton == ButtonState.Pressed)
            {
                if (_type == CommandType.Hide && CheckCoordinates(_ms))
                {
                    ExecuteActionHide();
                }
                else if (_type == CommandType.Show && CheckCoordinates(_ms))
                {
                    ExecuteActionShow();
                }
                else if (_type == CommandType.Move && _initialMouseDownInsideInterfaceObject && (_ms.X != _oms.X || _ms.Y != _oms.Y))
                {
                    ExecuteActionMove(_ms, _oms);
                }
                else if (_type == CommandType.Custom && CheckCoordinates(_ms))
                {
                    Execute();
                }
            }
        }
        #endregion
        //
        //
        // check mouse input
        #region Override Method - CheckMouseButton(MouseState ms)
        public override void CheckMouseButton(MouseState ms)
        {
            _ms = ms;
            // check if the mouse position is inside the InterfaceObjects bounds
            if (_initialMouseDownInsideInterfaceObject)
            {
                // switch on the Inputs set to this action
                switch (_mouseButton)
                {
                    // case: mouse button left
                    case MouseAction.MouseButtons.Left:
                        // check if the mouse is visible in the game instance
                        if (_target.Game.IsMouseVisible)
                        {
                            // Invoke the CheckMouseLeftButton() method
                            CheckMouseLeftButton();
                        }
                        break;
                    // case: mouse button middle
                    case MouseAction.MouseButtons.Middle:
                        // check if the mouse is visible in the game instance
                        if (_target.Game.IsMouseVisible)
                        {
                            // Invoke the CheckMouseLeftButton() method
                            CheckMouseMidButton();
                        }
                        break;
                    // case: mouse button right
                    case MouseAction.MouseButtons.Right:
                        // check if the mouse is visible in the game instance
                        if (_target.Game.IsMouseVisible)
                        {
                            // Invoke the CheckMouseLeftButton() method
                            CheckMouseRightButton();
                        }
                        break;
                }
            }

            _oms = _ms;
        }
        #endregion
        //
        #region Override Method - CheckKeyboard(KeyboardState ks)
        public override void CheckKeyboard(KeyboardState ks)
        {
            // empty, no reason to implement key input on MouseAction
        }
        #endregion
    }
}